package cn.stylefeng.guns.modular.demo.service;

import cn.stylefeng.guns.core.exception.BusinessException;
import cn.stylefeng.guns.core.exception.BusinessExceptionEnum;
import cn.stylefeng.guns.dao.IRuleLevelService;
import cn.stylefeng.guns.dao.IRuleService;
import cn.stylefeng.guns.dao.ISaleStockService;
import cn.stylefeng.guns.dao.ISupplierService;
import cn.stylefeng.guns.dao.entity.Rule;
import cn.stylefeng.guns.dao.entity.RuleLevel;
import cn.stylefeng.guns.dao.entity.SaleStock;
import cn.stylefeng.guns.modular.demo.controller.domain.RuleVO;
import cn.stylefeng.guns.modular.demo.controller.domain.SaveRuleRequest;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class RuleBizService {
    @Resource
    private IRuleService ruleService;
    @Resource
    private IRuleLevelService ruleLevelService;
    @Resource
    private ISupplierService supplierService;
    @Resource
    private ISaleStockService saleStockService;

    @Transactional(rollbackFor = Exception.class)
    public void saveRule(SaveRuleRequest saveRuleRequest) {
        String ruleId = saveRuleRequest.getRuleId();
        if (!StringUtils.isEmpty(ruleId)) {
            Rule rule = ruleService.getById(ruleId);
            Integer publicStatus = rule.getPublicStatus();
            if (Objects.equals(publicStatus, 1)) {
                throw new BusinessException(BusinessExceptionEnum.BUSINESS_PUBLIC);
            }
        }

        Rule entity = req2do(saveRuleRequest);
        boolean b = ruleService.saveOrUpdate(entity);

        List<RuleLevel> oldList = ruleLevelService.list(Wrappers.<RuleLevel>lambdaQuery().eq(RuleLevel::getRuleId, ruleId));

        List<SaveRuleRequest.RuleLevelRequest> ruleLevelList = saveRuleRequest.getRuleLevelList();
        List<RuleLevel> collect = ruleLevelList.stream().map(r -> {
            RuleLevel ruleLevel = req2do(r);
            ruleLevel.setRuleId(entity.getRuleId());
            return ruleLevel;
        }).collect(Collectors.toList());
        ruleLevelService.saveOrUpdateBatch(collect);
        Set<String> oldSet = ruleLevelList.stream().map(SaveRuleRequest.RuleLevelRequest::getRuleLevelId).filter(Objects::nonNull).collect(Collectors.toSet());

        List<String> removeId = oldList.stream().map(RuleLevel::getRuleLevelId).filter(r -> !oldSet.contains(r)).collect(Collectors.toList());
        ruleLevelService.removeBatchByIds(removeId);
    }


    @Transactional(rollbackFor = Exception.class)
    public RuleVO getDetail(String ruleId) {
        Rule rule = ruleService.getById(ruleId);
        if (Objects.isNull(rule)) {
            throw new BusinessException(BusinessExceptionEnum.BUSINESS_DATA_NOT_EXITS);
        }
        RuleVO ruleVO = do2vo(rule);

        List<RuleLevel> list = ruleLevelService.list(Wrappers.<RuleLevel>lambdaQuery().eq(RuleLevel::getRuleId, ruleId));
        List<RuleVO.RuleLevelVO> collect = list.stream().map(this::do2vo).sorted(Comparator.comparing(RuleVO.RuleLevelVO::getMinCount)).collect(Collectors.toList());
        ruleVO.setRuleLevelList(collect);
        return ruleVO;
    }

    private RuleVO do2vo(Rule rule) {
        if (rule == null) {
            return null;
        }
        RuleVO ruleVO = new RuleVO();
        ruleVO.setRuleId(rule.getRuleId());
        ruleVO.setName(rule.getName());
        ruleVO.setPublicStatus(rule.getPublicStatus());
        ruleVO.setPublicTime(rule.getPublicTime());
        ruleVO.setStairType(rule.getStairType());
        ruleVO.setMoney(rule.getMoney());
        ruleVO.setTicket(rule.getTicket());
        ruleVO.setRemark(rule.getRemark());
        ruleVO.setCreateTime(rule.getCreateTime().getTime());
//        ruleVO.setCreateUser(rule.getCreateUser());
//        ruleVO.setUpdateTime(rule.getUpdateTime());
//        ruleVO.setUpdateUser(rule.getUpdateUser());
        return ruleVO;
    }

    private RuleVO.RuleLevelVO do2vo(RuleLevel ruleLevel) {
        if (ruleLevel == null) {
            return null;
        }
        RuleVO.RuleLevelVO ruleLevelVO = new RuleVO.RuleLevelVO();
        ruleLevelVO.setRuleLevelId(ruleLevel.getRuleLevelId());
        ruleLevelVO.setMinCount(ruleLevel.getMinCount());
        ruleLevelVO.setMaxCount(ruleLevel.getMaxCount());
        ruleLevelVO.setRebateAmount(ruleLevel.getRebateAmount().divide(new BigDecimal(100)));
        return ruleLevelVO;
    }


    @Transactional(rollbackFor = Exception.class)
    public void deleteRule(String ruleId) {
        if (!StringUtils.isEmpty(ruleId)) {
            Rule rule = ruleService.getById(ruleId);
            Integer publicStatus = rule.getPublicStatus();
            if (Objects.equals(publicStatus, 1)) {
                throw new BusinessException(BusinessExceptionEnum.BUSINESS_PUBLIC);
            }
        }
        boolean b = ruleService.removeById(ruleId);
        ruleLevelService.deleteByRule(ruleId);
    }

//    @Transactional(rollbackFor = Exception.class)
//    public void cancelRule(String ruleId) {
    //todo 取消规则
//
//        Rule rule = ruleService.getById(ruleId);
//        if (Objects.isNull(rule)) {
//            throw new BusinessException(BusinessExceptionEnum.BUSINESS_DATA_NOT_EXITS);
//        }
//        rule.setPublicStatus(-2);
//        ruleService.updateById(rule);
//
//        saleStockService.update(Wrappers.<SaleStock>lambdaQuery().eq(SaleStock::getAuditLogId, ruleId))
//
//        //todo
//        Integer publicStatus = rule.getPublicStatus();
//        if (Objects.equals(publicStatus, 1)) {
//            throw new BusinessException(BusinessExceptionEnum.BUSINESS_PUBLIC);
//        }
//        boolean b = ruleService.removeById(ruleId);
//        ruleLevelService.deleteByRule(ruleId);
//    }


    private Rule req2do(SaveRuleRequest request) {
        if (request == null) {
            return null;
        }
        Rule rule = new Rule();
        rule.setRuleId(request.getRuleId());
        rule.setName(request.getName());
        rule.setPublicStatus(0);
        rule.setStairType(request.getStairType());
        rule.setMoney(request.getMoney());
        rule.setRemark(request.getRemark());
        rule.setTicket(request.getTicket());
        return rule;
    }

    private RuleLevel req2do(SaveRuleRequest.RuleLevelRequest request) {
        if (request == null) {
            return null;
        }
        RuleLevel ruleLevel = new RuleLevel();
        ruleLevel.setRuleLevelId(request.getRuleLevelId());
        ruleLevel.setMinCount(request.getMinCount());
        ruleLevel.setMaxCount(request.getMaxCount());
        ruleLevel.setRebateAmount(request.getRebateAmount().multiply(new BigDecimal(100)));
        return ruleLevel;
    }


}
